﻿//++
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// Module Name:
//
//    RuleDescription.cs
//
// Abstract:
//    
//    Encapsulates the rule properties of interest.  This class simplifies the task of describing a
//    rule - usign NotificationRuleItem would have been too cumbersome for this.
//
//    Note: THIS CODE IS NOT TO BE SHIPPED.
//
//--

using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Microsoft.EnhancedReminders;

namespace Microsoft.EnhancedRemindersTools
{
    internal sealed class RuleDescription
    {
        private static Regex _ruleRegex = new Regex(@"Rule name=(?<name>[^,]+), enabled=(?<enabled>[^,]+), type=(?<type>[^,]+), timestamp=(?<timestamp>[^,]+), conditions=(?<conditions>(.+)), NotifyChannels=(?<channels>[^,]+), JoinNowChannels=(?<joinnowchannels>[^,]+)", RegexOptions.Compiled);

        private readonly string _name;
        private readonly bool _isEnabled;
        private readonly MailboxType _type;
        private readonly DateTime _timestamp;
        private readonly string[] _conditions;
        private readonly List<Guid> _notificationChannels = new List<Guid>();
        private readonly List<Guid> _joinNowChannels = new List<Guid>();

        /// <summary>
        /// Ctor.
        /// </summary>
        /// <param name="ruleInfo">The rule description to parse.</param>
        internal RuleDescription(string ruleInfo)
        {
            Debug.Assert(!String.IsNullOrEmpty(ruleInfo), "ruleInfo");

            Match match = _ruleRegex.Match(ruleInfo);
            if (!match.Success)
            {
                throw new FormatException("Failed to parse rule description: " + ruleInfo);
            }

            _name = match.Groups["name"].Value;
            _isEnabled = bool.Parse(match.Groups["enabled"].Value);

            _type = (MailboxType)Enum.Parse(typeof(MailboxType), match.Groups["type"].Value);
            _timestamp = DateTime.Parse(match.Groups["timestamp"].Value);
            _conditions = match.Groups["conditions"].Value.Split(new char[] { '+' }, StringSplitOptions.RemoveEmptyEntries);

            PopulateChannelIds(match.Groups["channels"].Value, _notificationChannels);
            PopulateChannelIds(match.Groups["joinnowchannels"].Value, _joinNowChannels);

            Debug.Assert(_notificationChannels.Count > 0 || _joinNowChannels.Count > 0, "Expecting notification or join now channels");
        }

        /// <summary>
        /// Parse a list of channel IDs into a list of Guids.
        /// </summary>
        /// <param name="channelIds">The string of '+' separated channel IDs </param>
        /// <param name="guids">The Guid list to populate.</param>
        private void PopulateChannelIds(string channelIds, List<Guid> guids)
        {
            Debug.Assert(guids != null, "guids");
            Debug.Assert(guids.Count == 0, "guids list should be empty");

            if (String.IsNullOrEmpty(channelIds))
            {
                return;
            }

            string[] idStrings = channelIds.Split(new char[] { '+' }, StringSplitOptions.RemoveEmptyEntries);

            Debug.Assert(idStrings != null, "idStrings");
            Debug.Assert(idStrings.Length > 0, "idStrings.Length > 0");

            foreach (string id in idStrings)
            {
                guids.Add(new Guid(id));
            }
        }

        /// <summary>
        /// True if the rule is enabled.
        /// </summary>
        internal bool IsEnabled
        {
            get
            {
                return _isEnabled;
            }
        }

        /// <summary>
        /// The rule type.
        /// </summary>
        internal MailboxType Type
        {
            get
            {
                return _type;
            }
        }

        /// <summary>
        /// Rule creation time.
        /// </summary>
        internal DateTime Timestamp
        {
            get
            {
                return _timestamp;
            }
        }

        /// <summary>
        /// The selected conditions.
        /// </summary>
        internal string[] Conditions
        {
            get
            {
                return _conditions;
            }
        }

        /// <summary>
        /// Notification channels.
        /// </summary>
        internal List<Guid> NotificationChannels
        {
            get
            {
                return _notificationChannels;
            }
        }

        /// <summary>
        /// Join now channels.
        /// </summary>
        internal List<Guid> AutoJoinChannels
        {
            get
            {
                return _joinNowChannels;
            }
        }
    }
}
